# directories
BUILD:=.build
PDFDEST:=pdf
MOBIDEST:=mobi
EPUBDEST:=epub
DOWNLOAD:=$(BUILD)/download
BUILDTMP:=$(shell pwd)/$(BUILD)/tmp

# programmes
XSLTPROC:=xsltproc
GNUPLOT:=gnuplot
R:=R
KINDLEGEN:=kindlegen
INKSCAPE:=inkscape
ZIP:=zip
XVFB:=xvfb-run -a

# download locations
PMML2SVGZIP:=http://heanet.dl.sourceforge.net/project/pmml2svg/pmml2svg/pMML2SVG-0.8.5.zip
DOCBOOK5ZIP:=http://www.docbook.org/xml/5.0/docbook-5.0.zip

# download base names
PMML2SVGZIPBASE:=$(basename $(notdir $(PMML2SVGZIP)))

# data files
SAXONJAR:=/usr/share/java/saxonb.jar
XHTMLSTRICT:=/usr/share/xml/xhtml-relaxng/xhtml-strict.rng
PMML2SVG:=$(BUILD)/$(PMML2SVGZIPBASE)/XSLT2/pmml2svg.xsl

# source files
XHTMLS:=$(wildcard *.xhtml)
PLOTS:=$(filter-out src/flash-integrity.plot,$(wildcard src/*.plot))
RS:=$(wildcard src/*.r)
DOCUMENTS:=$(filter-out source-code.xhtml about.xhtml,$(wildcard *.xhtml) $(wildcard *.atom))

# escaped file names
XHTMLESC:=$(subst :,\:,$(XHTMLS))

# target files
BUILDRAW:=$(addprefix $(BUILD)/,$(basename $(DOCUMENTS)))
PPXHTMLS:=$(addprefix $(BUILD)/,$(XHTMLS))
DOCBOOKS:=$(addsuffix .docbook,$(BUILDRAW))
PDFS:=$(addsuffix .pdf,$(BUILDRAW))
OPFS:=$(addsuffix .opf,$(BUILDRAW))
MOBIS:=$(addsuffix .mobi,$(BUILDRAW))
EPUBS:=$(addsuffix .epub,$(BUILDRAW))
SVGS:=$(addsuffix .svg,$(basename $(notdir $(PLOTS))) $(basename $(notdir $(RS))))
OPFXHTMLS:=$(addprefix $(BUILD)/,$(addsuffix .opf.xhtml,$(basename $(notdir $(wildcard *.xhtml)))))

# escaped target file names
PPXHTMLESC:=$(subst :,\:,$(PPXHTMLS))
DOCBOOKESC:=$(subst :,\:,$(DOCBOOKS))
PDFESC:=$(subst :,\:,$(PDFS))
OPFESC:=$(subst :,\:,$(OPFS))
MOBIESC:=$(subst :,\:,$(MOBIS))
EPUBESC:=$(subst :,\:,$(EPUBS))
OPFXHTMLESC:=$(subst :,\:,$(OPFXHTMLS))

BUILDD:=$(BUILD)/.volatile
XSLTPROCARGS:=--stringparam baseURI "http://$(canonicalDomain)" --stringparam documentRoot "$$(pwd)" --param licence "document('$$(pwd)/$(BUILD)/licence.xml')" --stringparam builddir $(BUILD)

# don't delete intermediary files
.SECONDARY:

# meta rules
update: index pdfs mobis epubs install

all: fortune index svgs pdfs mobis epubs
run: run-fortune
clean:
	rm -f $(BUILD)/*; true
	rm -rf $(BUILDTMP); true
scrub: clean
	rm -rf $(BUILD)

index: index.xml

svgs: $(SVGS)
docbooks: $(DOCBOOKESC)
pdfs: $(PDFESC)
opfs: $(OPFESC)
mobis: $(MOBIESC)
epubs: $(EPUBESC)

install: install-pdf install-mobi install-epub
install-pdf: $(PDFDEST)/.volatile $(addprefix $(PDFDEST)/,$(notdir $(PDFESC)))
install-mobi: $(MOBIDEST)/.volatile $(addprefix $(MOBIDEST)/,$(notdir $(MOBIESC)))
install-epub: $(EPUBDEST)/.volatile $(addprefix $(EPUBDEST)/,$(notdir $(EPUBESC)))

uninstall: uninstall-pdf

validate: validate-docbook validate-xhtml

# .volatile files
$(BUILDD):
	mkdir -p $(BUILD); true
	ln -s $$(pwd)/png $(BUILD)/png
	ln -s $$(pwd)/jpeg $(BUILD)/jpeg
	ln -s $$(pwd) $(BUILD)/svg
	touch $(BUILDD)

$(DOWNLOAD)/.volatile:
	mkdir $(DOWNLOAD); true
	touch $(DOWNLOAD)/.volatile

$(PDFDEST)/.volatile:
	mkdir -p $(PDFDEST); true
	touch $@

$(MOBIDEST)/.volatile:
	mkdir -p $(MOBIDEST); true
	touch $@

$(EPUBDEST)/.volatile:
	mkdir -p $(EPUBDEST); true
	touch $@

# css files (for epub/kindle)
$(BUILD)/book.css: css/book.css $(BUILDD)
	cp $< $@

$(BUILD)/cover.css: css/cover.css $(BUILDD)
	cp $< $@

# build data file downloads
$(DOWNLOAD)/docbook-5.0.zip: $(DOWNLOAD)/.volatile
	wget '$(DOCBOOK5ZIP)' -cO $@
	touch $@

$(DOWNLOAD)/$(PMML2SVGZIPBASE).zip: $(DOWNLOAD)/.volatile
	wget '$(PMML2SVGZIP)' -cO $@
	touch $@

# extract downloaded data files
$(BUILD)/docbook-5.0/VERSION: $(DOWNLOAD)/docbook-5.0.zip
	unzip $< -d $(BUILD)
	touch $@

$(BUILD)/$(PMML2SVGZIPBASE)/RELEASE: $(DOWNLOAD)/$(PMML2SVGZIPBASE).zip
	unzip $< -d $(BUILD)
	touch $@

$(PMML2SVG): $(BUILD)/$(PMML2SVGZIPBASE)/RELEASE
	touch $@

# install pattern rules
$(PDFDEST)/%.pdf: $(BUILD)/%.pdf
	install $< $@

$(MOBIDEST)/%.mobi: $(BUILD)/%.mobi
	install $< $@

$(EPUBDEST)/%.epub: $(BUILD)/%.epub
	install $< $@

uninstall-pdf:
	rm -f $(addprefix $(PDFDEST)/,$(notdir $(PDFS)))

uninstall-mobi:
	rm -f $(addprefix $(MOBIDEST)/,$(notdir $(MOBIS)))

uninstall-epub:
	rm -f $(addprefix $(EPUBDEST)/,$(notdir $(EPUBS)))

# XML validation rules
validate-docbook: $(DOCBOOKESC) $(BUILD)/docbook-5.0/VERSION
	for i in $^; do ([ "$$(basename $$i)" != "VERSION" ] && (jing -C $(BUILD)/docbook-5.0/catalog.xml $(BUILD)/docbook-5.0/rng/docbook.rng "$$i" || echo "validation failed for '$$i'")) || true; done; true

validate-xhtml: $(XHTMLESC)
	for i in $^; do cp "$$i" "$(BUILD)/xhtml-tmp.xml"; jing $(XHTMLSTRICT) "$(BUILD)/xhtml-tmp.xml" || echo "validation failed for '$$i'"; done; true

# special build data files
$(BUILD)/licence.xml: COPYING
	echo "<?xml version='1.0' encoding='utf-8'?><legalnotice xmlns='http://docbook.org/ns/docbook' version='5.0'><para><![CDATA[" > $@
	sed -e "s:^$$:]]></para><para><!\[CDATA\[:" < $< >> $@
	echo "]]></para></legalnotice>" >> $@

# pattern rule to generate preprocessed XHTMLs
$(BUILD)/%.xhtml: %.xhtml $(BUILDD) $(BUILD)/licence.xml xslt/xhtml-pre-process.xslt
	$(XSLTPROC) $(XSLTPROCARGS) xslt/xhtml-pre-process.xslt $< > $@

# pattern rule to generate merged/preprocessed ATOMs
$(BUILD)/%.atom: %.atom $(BUILDD) $(BUILD)/licence.xml xslt/atom-merge.xslt xslt/xhtml-pre-process.xslt *.atom
	$(XSLTPROC) $(XSLTPROCARGS) xslt/atom-merge.xslt $< | \
		$(XSLTPROC) $(XSLTPROCARGS) xslt/xhtml-pre-process.xslt - > $@

# pattern rules to generate DocBook files
$(BUILD)/%.docbook: %.xhtml $(BUILDD) $(BUILD)/licence.xml xslt/docbook-transcode-xhtml.xslt
	$(XSLTPROC) $(XSLTPROCARGS) --param dblatexWorkaround 1 xslt/docbook-transcode-xhtml.xslt $< > $@

$(BUILD)/%.docbook: %.atom $(BUILDD) $(BUILD)/licence.xml xslt/docbook-transcode-xhtml.xslt xslt/docbook-transcode-atom.xslt
	$(XSLTPROC) $(XSLTPROCARGS) xslt/atom-merge.xslt $< | \
	    $(XSLTPROC) $(XSLTPROCARGS) --param dblatexWorkaround 1 xslt/docbook-transcode-xhtml.xslt - |\
		$(XSLTPROC) $(XSLTPROCARGS) --param dblatexWorkaround 1 xslt/docbook-transcode-atom.xslt - > $@

# pattern rule to generate PDFs
$(BUILD)/%.pdf: $(BUILD)/%.docbook $(BUILDD)
	dblatex --pdf $< -o $@
#	xmlto -o $(BUILD) --skip-validation --with-dblatex pdf $<
#	xsltproc -xinclude -o $<.fo /usr/share/xml/docbook/stylesheet/docbook-xsl-ns/fo/docbook.xsl $<
#	fop $<.fo -pdf $@

# pattern rules to generate EPUB/MOBI content
$(BUILD)/%/mimetype: $(BUILDD)
	mkdir -p $(BUILD)/$*
	echo 'application/epub+zip'>$@
	ln -s $$(pwd)/png $(BUILD)/$*/png
	ln -s $$(pwd)/jpeg $(BUILD)/$*/jpeg

$(BUILD)/%/META-INF/container.xml: $(BUILD)/%/mimetype
	mkdir -p $(BUILD)/$*/META-INF
	echo '<?xml version="1.0"?>'\
		'<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container"><rootfiles>'\
		'<rootfile full-path="publication.opf" media-type="application/oebps-package+xml"/>'\
		'</rootfiles></container>'>$@

$(BUILD)/%/book.css: css/book.css $(BUILD)/%/mimetype
	cp $< $@

$(BUILD)/%/cover.css: css/cover.css $(BUILD)/%/mimetype
	cp $< $@

$(BUILD)/%/publication.opf: $(BUILD)/%.xhtml $(BUILD)/%/META-INF/container.xml $(BUILD)/licence.xml xslt/opf-transcode-xhtml.xslt $(PMML2SVG)
	$(XSLTPROC) $(XSLTPROCARGS) xslt/opf-transcode-xhtml.xslt $< > $@~
	for i in $(BUILD)/$*/content.xhtml; do\
		echo converting MathML to SVG: $$i;\
		CLASSPATH=$(SAXONJAR) java net.sf.saxon.Transform -ext:off -s:$$i -xsl:$(PMML2SVG) -o:$$i initSize=14 minSize=4 svgMasterUnit='pt';\
		rm -rf $(BUILD)/$*/tmp; mkdir -p $(BUILD)/$*/tmp || true;\
		$(XSLTPROC) $(XSLTPROCARGS) --stringparam tmpdir $$(pwd)/$(BUILD)/$*/tmp -o $$i xslt/xhtml-split-svg-opf.xslt $$i;\
		for j in $(BUILD)/$*/tmp/*.svg; do [ ! -e $$j ] || ( echo " - converting SVG text to outlines: $$j" && $(XVFB) $(INKSCAPE) --with-gui --verb EditSelectAll --verb ObjectToPath --verb FileSave --verb FileQuit $$j ); done;\
		$(XSLTPROC) $(XSLTPROCARGS) -o $$i xslt/xhtml-post-process-opf.xslt $$i;\
		rm -rf $(BUILD)/$*/tmp;\
	done
	mv $@~ $@

$(BUILD)/%/publication.opf: $(BUILD)/%.atom $(BUILD)/%/META-INF/container.xml $(BUILD)/licence.xml xslt/opf-transcode-atom.xslt $(PMML2SVG)
	$(XSLTPROC) $(XSLTPROCARGS) xslt/opf-transcode-atom.xslt $< > $@~
	for i in $(BUILD)/$*/content-*.xhtml; do\
		echo converting MathML to SVG: $$i;\
		CLASSPATH=$(SAXONJAR) java net.sf.saxon.Transform -ext:off -s:$$i -xsl:$(PMML2SVG) -o:$$i initSize=14 minSize=4 svgMasterUnit='pt';\
		rm -rf $(BUILD)/$*/tmp; mkdir -p $(BUILD)/$*/tmp || true;\
		$(XSLTPROC) $(XSLTPROCARGS) --stringparam tmpdir $$(pwd)/$(BUILD)/$*/tmp -o $$i xslt/xhtml-split-svg-opf.xslt $$i;\
		for j in $(BUILD)/$*/tmp/*.svg; do [ ! -e $$j ] || ( echo " - converting SVG text to outlines: $$j" && $(XVFB) $(INKSCAPE) --with-gui --verb EditSelectAll --verb ObjectToPath --verb FileSave --verb FileQuit $$j ); done;\
		$(XSLTPROC) $(XSLTPROCARGS) -o $$i xslt/xhtml-post-process-opf.xslt $$i;\
		rm -rf $(BUILD)/$*/tmp;\
	done
	mv $@~ $@

# pattern rule to generate MOBIs
$(BUILD)/%.mobi: $(BUILD)/%/publication.opf $(BUILD)/%/book.css $(BUILD)/%/cover.css
	cd $(BUILD)/$* && $(KINDLEGEN) publication.opf -o $(notdir $@) || true
	mv $(BUILD)/$*/$(notdir $@) $(BUILD)

$(BUILD)/%.epub: $(BUILD)/%/publication.opf $(BUILD)/%/book.css $(BUILD)/%/cover.css
	rm -f $@
	cd $(BUILD)/$* && $(ZIP) -0 ../$(notdir $@) mimetype && $(ZIP) ../$(notdir $@) META-INF/container.xml publication.opf $(shell $(XSLTPROC) xslt/opf-print-manifest.xslt $<)

# pattern rule for gnuplot graphs
%.svg: src/%.plot xslt/clean.xslt
	$(GNUPLOT)\
		-e 'set terminal svg size 1200,600 dynamic fname "sans-serif"'\
		$< > $@
	$(XSLTPROC) $(XSLTPROCARGS) -o $@ xslt/clean.xslt $@

# pattern rule for R graphs
%.svg: src/%.r
	$(R) --no-save < $<

# global navigation index
index.xml: $(BUILD)/everything.atom xslt/atom-style-default.xslt xslt/atom-sort.xslt xslt/index-transcode-atom.xslt
	$(XSLTPROC) $(XSLTPROCARGS) xslt/atom-style-default.xslt $< |\
		$(XSLTPROC) $(XSLTPROCARGS) xslt/atom-sort.xslt - |\
		$(XSLTPROC) $(XSLTPROCARGS) xslt/index-transcode-atom.xslt - > $@

# setup
setup:
	mkdir css jpeg png svg xslt || true
	for j in css jpeg; do cd $$j; for i in $(OXYSALT)/$$j/*; do rm -f $$(basename $$i) && ln -s $$i; done; cd ..; done
